/*
 * InputAspect.aj
 * 
 *  author: Daniel Rudigier
 *    date: 08.12.2008
 * 
 * 
 */
package at.momberban2.me.aspects;

import at.syncme.framework.Event;
import at.momberban2.me.game.M2Event;
import at.momberban2.me.game.M2Game;
import at.momberban2.me.aspects.DisplayAspect.Render;
import javax.microedition.lcdui.game.GameCanvas;

/**
 * read from input. obviously no cross-cutting concern, but canvas (gamecanvas) 
 * is mixing input and display together. a canvas should be responsible for display 
 * only, this input aspect therefore splits input handling and display handling. 
 * 
 * @author Daniel Rudigier
 *
 */
public aspect InputAspect {
    private Render render;
    
    private M2Game game;
    
    private int currentMove;
    
    pointcut midletInit(): call (at.momberban2.me.game.M2Game.new());
    
    pointcut initCanvas(): execution (Render at.momberban2.me.aspects.DisplayAspect.Render.ready());
    
    pointcut keyPressed(): execution (int at.momberban2.me.aspects.DisplayAspect.Render.actionCode(int));
    
    //pointcut keyReleased(): execution (void javax.microedition.lcdui.game.GameCanvas.keyReleased(int));
    
    pointcut gameUpdate(): execution (void at.momberban2.me.game.M2GameState.updateGame());
    
    after() returning (M2Game g): midletInit() {
        System.out.println("init input aspect.");

        this.game = g;
    }
        
    /**
     * connect me to the renderer
     */
    after() returning (Render r): initCanvas() {
        this.render = r;        
    }
    
    /**
     * action keys
     */
    after() returning (int action): keyPressed() {
        if (action == GameCanvas.FIRE 
                || action == GameCanvas.GAME_A_PRESSED) {
            event(M2Event.BOMB_PLANTED, Event.PRIORITY_HIGH);
        }
    }
    
    /*
    after() returning (int keyCode): keyReleased() {
        System.out.println("released" + keyCode);
    }
    */
    
    after(): gameUpdate() {
        int keyState = this.render.getKeyStates();
        int move = M2Event.MOVE_STOP;
        
        if ((keyState & GameCanvas.LEFT_PRESSED) != 0) {
            move = M2Event.MOVE_LEFT;
        } else if ((keyState & GameCanvas.RIGHT_PRESSED) != 0) {
            move = M2Event.MOVE_RIGHT;
        } else if ((keyState & GameCanvas.UP_PRESSED) != 0) {
            move = M2Event.MOVE_UP;
        } else if ((keyState & GameCanvas.DOWN_PRESSED) != 0) {
            move = M2Event.MOVE_DOWN;
        } else {
            // don' care
        }
        
        // only after direction change
        if (move != this.currentMove) {
            this.currentMove = move;
            
            event((short) move, Event.PRIORITY_LOW);
        }
    }
    
    private void event(short id, byte priority) {
        // TODO: do not allow this directly!, call the algorithm
        this.game.gameEvent(Event.create(id, priority));
    }
    

}
